<?php

namespace app\worker\controller\kefu;

use Throwable;
use ba\Filesystem;
use think\Response;
use think\facade\Db;
use app\common\library\Upload;
use app\admin\model\kefu\User;
use app\admin\model\kefu\Group;
use app\worker\library\kefu\Common;
use app\common\controller\Frontend;
use app\admin\library\Auth as AdminAuth;
use app\common\library\token\TokenExpirationException;

/**
 * 客服 http Index 控制器
 */
class HttpIndex extends Frontend
{
    protected array $noNeedLogin = ['index', 'upload', 'user', 'csr', 'group', 'buildSuffixSvg', 'ring'];

    /**
     * 客服系统配置
     */
    protected array $config;

    /**
     * 管理员验权类
     */
    protected ?AdminAuth $adminAuth = null;

    public function initialize(): void
    {
        parent::initialize();

        $configData = Db::name('kefu_config')->select();
        foreach ($configData as $item) {
            $this->config[$item['name']] = $item['value'];
        }

        $wsConfig                       = config('worker_ws');
        $this->config['wss_switch']     = !empty($wsConfig['gateway']['transport']) && $wsConfig['gateway']['transport'] == 'ssl';
        $this->config['websocket_port'] = $wsConfig['gateway']['port'];
    }

    public function index(): void
    {
        // 输出到前台的配置排除
        $config = [
            'except' => [
                'tourist_switch',
                'csr_distribution',
                'csr_distribution_full_manual',
                'new_user_msg',
                'trajectory_save',
            ],
            'array'  => ['sliders', 'send_goods_identity', 'send_orders_identity'],// 逗号分隔的
            'br'     => ['not_start_paths'],// 一行一个的
        ];
        foreach ($config['except'] as $cKey) {
            if (array_key_exists($cKey, $this->config)) {
                unset($this->config[$cKey]);
            }
        }
        foreach ($config['array'] as $cKey) {
            if (array_key_exists($cKey, $this->config)) {
                $this->config[$cKey] = explode(',', $this->config[$cKey]);
                $this->config[$cKey] = array_filter($this->config[$cKey]);
            }
        }
        foreach ($config['br'] as $cKey) {
            if (array_key_exists($cKey, $this->config)) {
                $this->config[$cKey] = explode("\n", trim(str_replace("\r\n", "\n", $this->config[$cKey])));
            }
        }

        $this->success('', [
            'config' => $this->config,
        ]);
    }

    /**
     * 文件上传
     * @throws Throwable
     */
    public function upload(): void
    {
        $this->adminAuthInit();

        if ($this->config['tourist_file_switch'] == 'no' && !$this->isLogin()) {
            $this->error('您没有权限上传文件，请登录后重试！');
        }

        $file = $this->request->file('file');
        try {
            $upload     = new Upload($file);
            $attachment = $upload->upload(null, $this->adminAuth->isLogin() ? $this->adminAuth->id : 0, $this->auth->isLogin() ? $this->auth->id : 0);
            unset($attachment['create_time'], $attachment['quote']);
        } catch (Throwable $e) {
            $this->error($e->getMessage());
        }

        $this->success(__('File uploaded successfully'), [
            'file' => $attachment ?? []
        ]);
    }

    public function buildSuffixSvg(): Response
    {
        $suffix     = $this->request->param('suffix', 'file');
        $background = $this->request->param('background');
        $content    = build_suffix_svg((string)$suffix, (string)$background);
        return response($content, 200, ['Content-Length' => strlen($content)])->contentType('image/svg+xml');
    }

    /**
     * 供跨站下载来信提示音文件
     */
    public function ring(): void
    {
        $file = Filesystem::fsFit(public_path() . ltrim($this->config['ring'], '/'));
        header("Content-type:application/octet-stream");
        $filename = basename($file);
        header("Content-Disposition:attachment;filename = " . $filename);
        header("Accept-ranges:bytes");
        header("Accept-length:" . filesize($file));
        readfile($file);
    }

    /**
     * 客服界面 客服转接远程下拉
     * @throws Throwable
     */
    public function csr(): void
    {
        if (!$this->isCsr()) {
            $this->error('您没有权限访问，请登录后再试！');
        }

        $limit        = $this->request->get("limit/d", 10);
        $quickSearch  = $this->request->get("quickSearch/s", '');
        $initValue    = $this->request->get("initValue", '');
        $currentCsrId = $this->request->get("currentCsrId", 0);

        $where   = [];
        $where[] = ['user.identity', '=', 'csr'];
        $where[] = ['user.id', '<>', $currentCsrId];

        if ($quickSearch) {
            $quickSearchField = ['user.id', 'user.nickname', 'sysUser.nickname', 'admin.nickname'];
            $where[]          = [implode("|", $quickSearchField), "LIKE", '%' . str_replace('%', '\%', $quickSearch) . '%'];
        }

        if ($initValue) {
            $where[] = ['user.id', '=', $initValue];
            $limit   = 999999;
        }

        $res = User::alias(['kefu_user' => 'user'])
            ->withJoin(['sysUser', 'admin'], 'LEFT')
            ->where($where)
            ->order('user.create_time', 'desc')
            ->visible(['sysUser' => ['nickname'], 'admin' => ['nickname']])
            ->paginate($limit)
            ->each(function ($item) {
                $item->nickname = Common::trueValue([
                    $item->nickname,
                    $item->admin?->nickname,
                    $item->sysUser?->nickname,
                ]);
            });

        $this->success('', [
            'list'  => $res->items(),
            'total' => $res->total(),
        ]);
    }

    /**
     * 客服界面 用户分组远程下拉
     * @throws Throwable
     */
    public function group(): void
    {
        if (!$this->isCsr()) {
            $this->error('您没有权限访问，请登录后再试！');
        }

        $limit       = $this->request->get("limit/d", 10);
        $initValue   = $this->request->get("initValue", '');
        $quickSearch = $this->request->get("quickSearch/s", '');

        $where   = [];
        $where[] = ['type', '=', 'user'];

        if ($quickSearch) {
            $where[] = ['name', 'LIKE', '%' . str_replace('%', '\%', $quickSearch) . '%'];
        }
        if ($initValue) {
            $where[] = ['id', 'in', $initValue];
            $limit   = 999999;
        }

        $res = Group::where($where)
            ->order('weigh', 'desc')
            ->paginate($limit);

        $this->success('', [
            'list'  => $res->items(),
            'total' => $res->total(),
        ]);
    }

    /**
     * 客服界面 绑定会员远程下拉
     * @throws Throwable
     */
    public function user(): void
    {
        if (!$this->isCsr()) {
            $this->error('您没有权限访问，请登录后再试！');
        }

        $where       = [];
        $limit       = $this->request->get("limit/d", 10);
        $initValue   = $this->request->get("initValue", '');
        $quickSearch = $this->request->get("quickSearch/s", '');

        if ($quickSearch) {
            $where[] = ['username|nickname|id', 'LIKE', '%' . str_replace('%', '\%', $quickSearch) . '%'];
        }
        if ($initValue) {
            $where[] = ['id', 'in', $initValue];
            $limit   = 999999;
        }

        $res = \app\common\model\User::where($where)
            ->withoutField('password,salt,score,money')
            ->order('create_time', 'desc')
            ->paginate($limit);

        $this->success('', [
            'list'  => $res->items(),
            'total' => $res->total(),
        ]);
    }

    /**
     * 是否是客服代表
     * @throws Throwable
     */
    public function isCsr(): bool
    {
        $this->adminAuthInit();

        if ($this->auth->isLogin()) {
            $user = User::where('user_id', $this->auth->id)->find();
            if ($user && $user->identity == 'csr') {
                return true;
            }
        }

        if ($this->adminAuth->isLogin()) {
            $user = User::where('admin_id', $this->adminAuth->id)->find();
            if ($user && $user->identity == 'csr') {
                return true;
            }
        }

        return false;
    }

    /**
     * 检查是否有已经登录的【会员】或者【管理员】（非游客）
     * @throws Throwable
     */
    public function isLogin(): bool
    {
        $this->adminAuthInit();

        if ($this->auth->isLogin() || $this->adminAuth->isLogin()) {
            return true;
        }
        return false;
    }

    /**
     * 检查是否有已经登录的【会员】或者【管理员】
     * @throws Throwable
     */
    public function adminAuthInit(): void
    {
        if (!is_null($this->adminAuth)) {
            return;
        }

        $this->adminAuth = AdminAuth::instance();
        try {
            $baToken = get_auth_token();
            if ($baToken) $this->adminAuth->init($baToken);
        } catch (TokenExpirationException) {
        }
    }
}